home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 19
/
Aminet 19 (1997)(GTI - Schatztruhe)[!][Jun 1997].iso
/
Aminet
/
gfx
/
board
/
rtgmasdev.lha
/
demos
/
moon
/
MOON.C
< prev
next >
Wrap
C/C++ Source or Header
|
1996-10-12
|
22KB
|
826 lines
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <time.h>
#include <dos.h>
#include <string.h>
#include "SysInclude.h"
#include <rtgmaster/rtgmaster.h>
#include <rtgmaster/rtgsublibs.h>
#include <clib/rtgmaster_protos.h>
#include <pragmas/rtgmaster_pragmas.h>
#include <rtgmaster/rtgc2p.h>
#include "rtggadgets.h"
#include <libraries/asl.h>
#include <proto/console.h>
#include <proto/utility.h>
#define SMRTITLE ("Simplest ScreenMode Requester")
struct RtgScreen *RtgScreen;
struct ScreenReq *sr;
struct RTGMasterBase *RTGMasterBase;
struct Library *IntuitionBase;
struct Library *GfxBase;
struct Library *AslBase;
UBYTE *sadr;
framemode=2;
#include "random.h"
#include "boolean.h"
#include "fixed.h"
#include "world.h"
long clip_mask_x = map_size_x - 1;
long clip_mask_y = map_size_y - 1;
long scale_height = 128;
long world_size_x = map_size_x * scale_area;
long world_size_y = map_size_y * scale_area;
long max_alt = 255;
long min_alt = 0;
#define view_size 80
long view_start = view_size / 2;
long win_cen_x=160;
long win_cen_y=100;
long black =0;
long cursor_color=255;
typedef struct{
int x;
int y;
int z;
angle_t angle;
fixed sine;
fixed cosine;
}viewer_t;
static viewer_t viewer;
typedef struct{
int x1; /* Left */
int y1; /* Top */
int x2; /* Right */
int y2; /* Bottom */
int win_cen_x,win_cen_y;
int dither_mode;
} win_t;
static win_t win=
{
0, 0, 319, 199,0,0,5
};
typedef struct{
int y;
unsigned char color;
} col_t ;
static col_t col [ 321 ];
static col_t old_col [ 321 ];
typedef struct{
unsigned long r,g,b;
}color_t;
color_t colors[256];
ULONG cmap[800];
int Planar=FALSE;
ULONG c2psignal;
extern int __asm mul_and_div(register __d0 int a,register __d1 int b,register __d2 int c);
extern int __asm dot_product(register __d0 int u1,register __d1 int v1, register __d2 int u2, register __d3 int v2);
extern void __asm rotate(register __a0 void *x,register __a1 void *y,register __d0 int sine,register __d1 int cosine);
extern void __asm copy(register __a0 void *src,register __a1 void *dest,register __d0 ULONG method);
static unsigned char tmp_scr[200][320];
void ToScreen(struct RtgScreen *RtgScreen)
{
/*if(Planar==TRUE){
CallRtgC2P(RtgScreen,sadr,tmp_scr,c2psignal,0,0,320,200,c2p_1x1);
Wait(1<<c2psignal);
}else CopyRtgPixelArray(RtgScreen,sadr,tmp_scr,win.x1,0,win.x2-win.x1+1,200,0,0);
*/
copy(tmp_scr,sadr,0);
}
void view_overhead_map (struct RtgScreen *RtgScreen)
{
int start_x = (int) (viewer.x / scale_area) - win_cen_x;
int start_y = (int) (viewer.y / scale_area) - win_cen_y;
int x,y,map_y,map_x;
start_x &= clip_mask_x;
start_y &= clip_mask_y;
map_x = start_x;
for(y=0;y<200;++y){
map_y=(start_y+y)&clip_mask_y;
for(x=0;x<win.x2-win.x1; ++ x ){
map_x=(start_x+x+win.x1)&clip_mask_x;
tmp_scr[y][x]=(UBYTE)color_map[map_x][map_y];
}
}
ToScreen(RtgScreen);
{
int x1 = dot_product ( viewer.sine, viewer.cosine, 20, 0 ) + 160;
int y1 = dot_product ( -viewer.cosine, viewer.sine, 20, 0 ) + 100;
int x2 = dot_product ( viewer.sine, viewer.cosine, 30, 0 ) + 160;
int y2 = dot_product ( -viewer.cosine, viewer.sine, 30, 0 ) + 100;
DrawRtgLine(RtgScreen, sadr,255,x1,y1,x2,y2);
DrawRtgLine(RtgScreen, sadr,255,159, 99,162, 99);
DrawRtgLine(RtgScreen, sadr,255,162, 99,162,102);
DrawRtgLine(RtgScreen, sadr,255,162,102,159,102);
DrawRtgLine(RtgScreen, sadr,255,159,102,159, 99);
}
}
unsigned char calc_color(int map_x, int map_y)
{
return(color_map[map_x][map_y]);
}
static void draw_row(struct RtgScreen *RtgScreen)
{
int x,y;
for(x=win.x1;x<win.x2;++x){
if(col[x].y<0 )col[x].y=0; else if(col[x].y>199)col[x].y=199;
}
if(win.dither_mode==0){
for(x=win.x1;x<win.x2;++x){
tmp_scr[col[x].y][x-win.x1]=(unsigned char)col[x].color;
old_col[x].y =col[x].y;
old_col[x].color=col[x].color;
}
}else if(win.dither_mode==1){
for(x=win.x1;x<win.x2;++x){
if(old_col[x].y<=col[x].y){
for(y=old_col[x].y;y<col[x].y;y++){
tmp_scr[y][x-win.x1]=(unsigned char)old_col[x].color;
}
}
old_col[x].y =col[x].y;
old_col[x].color=col[x].color;
}
}else if(win.dither_mode==2){
for(x=win.x1;x<win.x2;++x){
int color=old_col[x].color;
int dcol=col[x].color-old_col[x].color;
int dy=col[x].y-old_col[x].y;
int scr_x=x-win.x1;
for(y=old_col[x].y;y<col[x].y;y++){
tmp_scr[y][scr_x]=(unsigned char)color;
color=old_col[x].color+(dcol)*((y-old_col[x].y+1)/dy);
}
old_col[x].y =col[x].y;
old_col[x].color=col[x].color;
}
}else{
for(x=win.x1;x<win.x2;++x){
int dif=col[x].y-old_col[x].y;
if(dif>0){
int color=old_col[x].color;
int den=col[x].y-old_col[x].y;
int num=col[x].color-color;
int color_inc;
int i=0,err=0;
int scr_x=x-win.x1;
if(num<0){color_inc=-1;num=-num;}
else color_inc=1;
while(i<dif){
tmp_scr[old_col[x].y+i][scr_x]=(unsigned char)color;
i++;
err+=num;
while(err>=den){
err -=den;
color+=color_inc;
}
}
}
old_col[x].y =col[x].y;
old_col[x].color=col[x].color;
}
}
}
static void view_3d(struct RtgScreen *RtgScreen)
{
const sz = 240;
int x;
int viewer_map_x=viewer.x/scale_area;
int viewer_map_y=viewer.y/scale_area;
int map_start_x, map_start_y;
int map_start_x_inc,map_start_y_inc;
int map_x_inc, map_y_inc;
int start_x, start_y;
#ifdef ALT19_03_96
if(viewer.angle < 450 || viewer.angle >= 3150 ){
map_start_x = (viewer_map_x-view_start) & clip_mask_x;
map_start_y = (viewer_map_y-view_start) & clip_mask_y;
map_start_x_inc = 0;
map_start_y_inc = 1;
map_x_inc = 1;
map_y_inc = 0;
start_x = -view_start * scale_area;
start_y = view_start * scale_area;
}else if( viewer.angle<1350 ){
map_start_x = (viewer_map_x+view_start) & clip_mask_x;
map_start_y = (viewer_map_y-view_start) & clip_mask_y;
map_start_x_inc = -1;
map_start_y_inc = 0;
map_x_inc = 0;
map_y_inc = 1;
start_x = view_start * scale_area;
start_y = view_start * scale_area;
}else if( viewer.angle<2250 ){
map_start_x = (viewer_map_x+view_start) & clip_mask_x;
map_start_y = (viewer_map_y+view_start) & clip_mask_y;
map_start_x_inc = 0;
map_start_y_inc = -1;
map_x_inc = -1;
map_y_inc = 0;
start_x = view_start * scale_area;
start_y = -view_start * scale_area;
}else{
map_start_x = (viewer_map_x-view_start) & clip_mask_x;
map_start_y = (viewer_map_y+view_start) & clip_mask_y;
map_start_x_inc = 1;
map_start_y_inc = 0;
map_x_inc = 0;
map_y_inc = -1;
start_x = -view_start * scale_area;
start_y = -view_start * scale_area;
}
#endif
if(viewer.angle < 450 || viewer.angle >= 3150 ){
map_start_x = (viewer_map_x-view_start) & clip_mask_x;
map_start_y = (viewer_map_y-view_start) & clip_mask_y;
map_start_x_inc = 0;
map_start_y_inc = 1;
map_x_inc = 1;
map_y_inc = 0;
start_x = -view_start * scale_area;
start_y = view_start * scale_area;
}else if( viewer.angle<1350 ){
map_start_x = (viewer_map_x+view_start) & clip_mask_x;
map_start_y = (viewer_map_y-view_start) & clip_mask_y;
map_start_x_inc = -1;
map_start_y_inc = 0;
map_x_inc = 0;
map_y_inc = 1;
start_x = view_start * scale_area;
start_y = view_start * scale_area;
}else if( viewer.angle<2250 ){
map_start_x = (viewer_map_x+view_start) & clip_mask_x;
map_start_y = (viewer_map_y+view_start) & clip_mask_y;
map_start_x_inc = 0;
map_start_y_inc = -1;
map_x_inc = -1;
map_y_inc = 0;
start_x = view_start * scale_area;
start_y = -view_start * scale_area;
}else{
map_start_x = (viewer_map_x-view_start) & clip_mask_x;
map_start_y = (viewer_map_y+view_start) & clip_mask_y;
map_start_x_inc = 1;
map_start_y_inc = 0;
map_x_inc = 0;
map_y_inc = -1;
start_x = -view_start * scale_area;
start_y = -view_start * scale_area;
}
start_x -= (viewer.x % scale_area);
start_y += (viewer.y % scale_area);
{
int world_x_inc = map_x_inc * scale_area;
int world_y_inc = -map_y_inc * scale_area;
int start_x_inc,start_y_inc;
int nr_rows;
rotate(&start_x, &start_y, viewer.sine,viewer.cosine);
rotate(&world_x_inc,&world_y_inc,viewer.sine,viewer.cosine);
start_x_inc= world_y_inc;
start_y_inc=-world_x_inc;
memset(tmp_scr,0,sizeof(tmp_scr));
for ( x = 0; x <win.x2-win.x1; ++ x ){
col[x].y=old_col[x].y = win.y2;
col[x].color=old_col[x].color = 0;
}
for(nr_rows=view_size/2;nr_rows>0;--nr_rows ){
int map_x=map_start_x;
int map_y=map_start_y;
int world_x=start_x;
int world_y=start_y;
int world_z=viewer.z-alt_map[map_x][map_y]*scale_height;
int last_sx=win.x2;
int last_sy=win.y1;
int last_color=0;
int nr_cols=view_size;
while(nr_cols>0){
if(world_y>0){
int sx=mul_and_div(world_x,sz,world_y)+win_cen_x;
int sy=mul_and_div(world_z,sz,world_y)+win_cen_y;
int color=calc_color(map_x,map_y);
if(sx>win.x1){
int den=sx-last_sx;
int num=color-last_color;
int color_inc;
int err,num2,last_sy_inc,err2;
if(num<0){color_inc=-1;num=-num;}else color_inc=1;
err=0;
num2=sy-last_sy;
if(num2<0){last_sy_inc=-1;num2=-num2;}else last_sy_inc=1;
err2=0;
if(last_sx<win.x1 ){
int delta=win.x1-last_sx;
err=num*delta%den;
last_color+=color_inc*num*delta/den;
err2=num2*delta%den;
last_sy+=last_sy_inc*num2*delta/den;
last_sx=win.x1;
}
if(sx>win.x2)sx=win.x2;
for(x=last_sx;x<sx;++x){
col[x].y =last_sy;
col[x].color=(unsigned char) last_color;
err+=num;
while(err >=den){
err-=den;
last_color+=color_inc;
}
err2+=num2;
while(err2>=den){
err2-=den;
last_sy+=last_sy_inc;
}
}
if(sx==win.x2)break;
}
last_sx=sx;
last_sy=sy;
last_color=color;
}
map_x=(map_x+map_x_inc)&clip_mask_x;
map_y=(map_y+map_y_inc)&clip_mask_y;
world_x+=world_x_inc;
world_y+=world_y_inc;
world_z =viewer.z - alt_map [map_x][map_y] * scale_height;
--nr_cols;
}
draw_row(RtgScreen);
start_x+=start_x_inc;
start_y+=start_y_inc;
map_start_x=(map_start_x+map_start_x_inc)&clip_mask_x;
map_start_y=(map_start_y+map_start_y_inc)&clip_mask_y;
}
}
for ( x = win.x1; x < win.x2; ++ x ){
col [x].y = win.y2;
col [x].color = calc_color (viewer_map_x, viewer_map_y);
}
draw_row(RtgScreen);
ToScreen(RtgScreen);
}
void set_palette(struct RtgScreen *RtgScreen)
{
int i;
memset(colors,0,sizeof(colors));
for(i=0;i<64;++i){
colors[i+1].r=(unsigned char)i;
colors[i+1].g=(unsigned char)(i*i/63);
colors[i+1].b=(unsigned char)(i*i/63);
}
colors[255].r =16;
colors[255].g =63;
colors[255].b =0;
{
UBYTE rr, rg, rb;
int x,i;
cmap[0] = 256 * 65536;
rr = 0;
rg = 0;
rb = 0;
x = 1;
for (i = 0; i < 64; i++) {
cmap[x++] = rr * 0x1111111;
cmap[x++] = rg * 0x1111111;
cmap[x++] = rb * 0x1111111;
rr += 3;
}
for (i = 0; i < 127; i++) {
cmap[x++] = rr * 0x1111111;
cmap[x++] = rg * 0x1111111;
cmap[x++] = rb * 0x1111111;
rg += 3;
}
for (i = 0; i < 60; i++) {
cmap[x++] = rr * 0x1111111;
cmap[x++] = rg * 0x1111111;
cmap[x++] = rb * 0x1111111;
rb += 3;
}
for (i = 0; i < 4; i++) {
cmap[x++]=0xFFFFFFFF;
cmap[x++]=0xFFFFFFFF;
cmap[x++]=0xFFFFFFFF;
}
cmap[x++]=0;
LockRtgScreen(RtgScreen);
LoadRGBRtg(RtgScreen, (APTR)cmap);
UnlockRtgScreen(RtgScreen);
}
}
int Clear_Screen(struct RtgScreen *RtgScreen)
{
memset(tmp_scr,0,sizeof(tmp_scr));
ToScreen(RtgScreen);
return(0);
}
typedef enum{cockpit_view,map_view}view_t;
void interact(struct RtgScreen *RtgScreen)
{
BYTE buffer[10];
float frames=0;
const clearance = 8 * scale_height;
const max_altitude = (max_alt+4) * scale_height;
int vel = 0;
int vz = 0;
int va = 0;
boolean done =FALSE;
view_t view =cockpit_view;
long t1,t2,anz_frames=0;
time(&t1);
viewer.x = 4 * scale_area;
viewer.y = 4 * scale_area;
viewer.z = color_map [4][4] * scale_height + clearance;
viewer.angle = 1800;
while ( ! done ){
int vx,vy,map_x,map_y;
viewer.angle += va;
while ( viewer.angle < 0 ) viewer.angle += 3600;
while ( viewer.angle >= 3600 ) viewer.angle -= 3600;
FIX_cos_sin ( viewer.angle, & viewer.cosine, & viewer.sine );
vx = mul_and_div ( vel, -viewer.sine, 65536 );
vy = mul_and_div ( vel, viewer.cosine, 65536 );
map_x = (int) (viewer.x / scale_area);
map_y = (int) (viewer.y / scale_area);
viewer.x += vx;
viewer.y += vy;
while(viewer.x< 0 ) viewer.x+=world_size_x;
while(viewer.x>=world_size_x) viewer.x-=world_size_x;
while(viewer.y< 0 ) viewer.y+=world_size_y;
while(viewer.y>=world_size_y) viewer.y-=world_size_y;
viewer.z += vz;
if(viewer.z<alt_map [map_x][map_y] * scale_height + clearance ){
viewer.z=alt_map [map_x][map_y] * scale_height + clearance;
vz =0;
}else if(viewer.z > max_altitude ){
viewer.z=max_altitude;
vz =0;
}
if(view==cockpit_view)view_3d(RtgScreen);
else view_overhead_map(RtgScreen);
if (framemode)
{
++anz_frames;
if(anz_frames>=10){
char gww[20];
float diff;
time(&t2);
diff=(t2-t1);
if(diff>0){
float g=(anz_frames)/diff;
diff=g;
}
sprintf(gww,"%5.1f",diff);
frames=diff;
if (framemode>1)
RtgText(RtgScreen,sadr,gww,5,0,180);
}
}
/* Key pollen */
if(RTGInputRecord.LastKey!=0){
RTGIe.ie_NextEvent = NULL;
RTGIe.ie_Class = IECLASS_RAWKEY;
RTGIe.ie_Code = RTGInputRecord.LastKey;
RTGIe.ie_Qualifier = 0;
RTGIe.ie_position.ie_addr = NULL;
RawKeyConvert(&RTGIe, buffer, 10, NULL);
RTGInputRecord.LastKey = 0;
switch(buffer[0]){
case -101:
switch(buffer[1]){
case 65 /*CURSORUP */: vz+=scale_height/2; break;
case 66 /*CURSORDOWN */: vz-=scale_height/2; break;
case 67 /*CURSORRIGHT*/: va += 5; break;
case 68 /*CURSORLEFT */: va -= 5; break;
case 48: /* F1 */
win.x1=0;
win.x2=319;
t1=t2;
anz_frames=0;
Clear_Screen(RtgScreen);
break;
case 49: /* F2 */
win.x1=20;
win.x2=299;
t1=t2;
anz_frames=0;
Clear_Screen(RtgScreen);
break;
case 50: /* F3 */
win.x1=40;
win.x2=279;
t1=t2;
anz_frames=0;
Clear_Screen(RtgScreen);
break;
case 51: /* F4 */
win.x1=60;
win.x2=259;
t1=t2;
anz_frames=0;
Clear_Screen(RtgScreen);
break;
case 52: /* F5 */
win.x1=80;
win.x2=239;
t1=t2;
anz_frames=0;
Clear_Screen(RtgScreen);
break;
case 53: /* F6 */
framemode=0;
break;
case 54: /* F7 */
framemode=1;
break;
case 55: /* F8 */
framemode=2;
break;
case 56: /* F9 */
win.dither_mode=(win.dither_mode==5)?0:win.dither_mode+1;
t1=t2;
anz_frames=0;
Clear_Screen(RtgScreen);
break;
case 57: /* F10 */
win.dither_mode=(win.dither_mode==0)?5:win.dither_mode-1;
t1=t2;
anz_frames=0;
Clear_Screen(RtgScreen);
break;
default:
break;
}
break;
case 27:
case ' ': done=TRUE; break;
case '5': vel = 0; va = 0; vz = 0; break;
case 'm':
view=(view==map_view)?cockpit_view:map_view;
t1=t2;
anz_frames=0;
break;
case 'n': viewer.angle = 0; break;
case 'e': viewer.angle = 900; break;
case 's': viewer.angle = 1800; break;
case 'w': viewer.angle = 2700; break;
case 'r': viewer.angle = (viewer.angle + 1800) % 3600; break;
case '+':
case '=': vel -= scale_area / 8; break;
case '-': vel += scale_area / 8; break;
default:
break;
}
}
}
printf("Frames: %5.1f\n",frames);
}
const char * instructions =
"\n\"Moonbase\" 3D Landscape Demo\n"
"????????????????????????????\n\n"
"Use the mouse or arrow keys to steer. Other keys are:\n\n"
" + - Increase/Decrease forward velocity\n"
" m Toggle satellite view\n"
" Esc Quit\n"
"\nPress Enter to begin.\n"
"";
const char * closing_msg =
"Moonbase was written by James McNeill (mcneja@wwc.edu)\n"
"using Watcom C++ and the PMODE/W DOS extender.\n";
int CloseAll(int mode)
{
if(GfxBase!=NULL)CloseLibrary(GfxBase);
if(IntuitionBase!=NULL)CloseLibrary(IntuitionBase);
if(RTGMasterBase!=NULL)CloseLibrary((struct Library *)RTGMasterBase);
if(AslBase!=NULL)CloseLibrary(AslBase);
return(0);
}
struct TagItem rtag[] = {
smr_ChunkySupport, (1<<9),
smr_PlanarSupport, -1,
smr_Buffers, 1,
smr_TitleText, (ULONG)"MOON Landscape Demo",
smr_MinWidth, 320,
smr_MinHeight, 200,
smr_MaxWidth, 320,
smr_MaxHeight, 240,
TAG_DONE, NULL
};
struct TagItem tacks[] = {
TAG_DONE, 0
};
struct TagItem gtag[] = {
grd_BytesPerRow, 0,
grd_Width, 0,
grd_Height, 0,
grd_Depth, 0,
grd_PixelLayout, 0,
grd_ColorSpace, 0,
grd_PlaneSize, 0,
grd_BusSystem, 0,
TAG_DONE, 0
};
int RTGScreen(void)
{
struct TagItem *tag;
c2psignal=AllocSignal(-1);
if(1){
if(NULL!=(RtgScreen = OpenRtgScreen(sr, tacks))){
if(NULL!=RTGGOpenInput()) {
RtgSetTextMode(RtgScreen,0,255,JAM1);
sadr=GetBufAdr(RtgScreen,0);
GetRtgScreenData(RtgScreen, gtag);
tag=FindTagItem(grd_PixelLayout, gtag);
if (tag->ti_Data == grd_PLANAR) Planar = TRUE;
else Planar = FALSE;
printf("Screen is %ld x %ld x %ld\n", gtag[1].ti_Data, gtag[2].ti_Data, gtag[3].ti_Data);
printf("Screenmode is %s\n",(Planar==TRUE)?"Planar":"Chunky");
set_palette(RtgScreen);
RTGGAddIPH();
interact(RtgScreen);
RTGGRemIPH();
RTGGCloseInput();
}
CloseRtgScreen(RtgScreen);
}else{
PutStr("Konnte RTG-Screen 8 Bit nicht öffnen\n");
}
}
FreeSignal(c2psignal);
return(TRUE);
}
int main(void)
{
if(RTGMasterBase=(struct RTGMasterBase *)OpenLibrary((STRPTR)"rtgmaster.library", 0)){
if (NULL!=(sr=RtgScreenModeReq(rtag)))
{
WORLD_generate ();
printf ( instructions );
if(IntuitionBase=OpenLibrary("intuition.library",0)){
if(GfxBase = OpenLibrary("graphics.library",0)){
if(AslBase=OpenLibrary("asl.library", 38L)){
RTGScreen();
}else PutStr("Konnte \"asl.library\" nicht öffnen\n");
}else PutStr("Konnte \"graphics.library\" nicht öffnen\n");
}else PutStr("Konnte \"intuition.library\" nicht öffnen\n");
CloseAll(0);
printf ( closing_msg );
}
else PutStr("Konnte keine Screenmodes finden\n");
}else PutStr("Konnte \"rtgmaster.library\" nicht öffnen\n");
return 0;
}